VIM 排序
当Ex命令与
:global一起组合使用时,也可以为[cmd]单独指定范围。Vim允许以:g/{pattern}为参考点,动态地设定范围。接下来,看看如何利用这一点,将CSS文件中每一条规则的所有属性均按照字母顺序排列。
用以下 CSS 文件作为演示。
global/unsorted.css
Line 1 html {
- margin: 0;
- padding: 0;
- border: 0;
5 font-size: 100%;
- font: inherit;
- vertical-align: baseline;
- }
- body {
10 line-height: 1.5;
- color: black;
- background: white;
- }
假设想把每一组规则内的属性都按照字母顺序排序。借助Vim的内置命令 :sort(参见:h :sort ![]),就可以实现这一功能。
0.1 对单条规则的属性进行排序
先用 :sort命令在该文件的子集上练练手(参见表15-1)。
首先,使用文本对象 vi{,可以轻易地选中一段由 {} 所围的文本块。然后,运行 :'<,'>sort,便可以将这些文本行按照字母顺序重新排列了。如果每次仅对一条规则进行排序,此法完全可以胜任,但假设我们遇到的是一个包含数百条规则的样式表呢?如果能把这一过程自动化岂不更好么?
表15-1 对文件的子集进行排序
| 按键操作 | 缓冲区内容 |
|---|---|
| html { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } | |
| vi{ | html { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } |
| :'<,'>sort | html { border: 0; font-size: 100%; font: inherit; margin: 0; padding: 0; vertical-align: baseline; } |
0.2 对所有规则的属性进行排序
其实,可以用一条 :global 命令对文件中所有规则的属性进行排序。假设在本例的样式表中运行以下命令。
➾ :g/{/ .+1,/}/-1 sort
最终会得到以下结果。
html {
border: 0;
font-size: 100%;
font: inherit;
margin: 0;
padding: 0;
vertical-align: baseline;
}
body {
background: white;
color: black;
line-height: 1.5;
}
这条排序命令会在每条规则的{} 块内执行。尽管本例中的样式表仅仅包含十几行文本,但对于内容更多的CSS文件,此法也同样适用。
这条命令很复杂,但掌握其机理后,将会由衷地赞叹 :global命令的强大。:global命令的标准格式如下。
:g/{pattern}/[cmd]
请牢记,Ex命令通常都会接受“范围”作为其参数(正如技巧28讨论的那样)。对于:global命令内部的 [cmd],该规则依然有效。因此,可以将命令的模板扩展成以下形式。
:g/{pattern}/[range][cmd]
实际上,可以用 :g/{pattern} 匹配作为参考点,动态设置 [cmd]的 [range]。. 符号通常表示光标所在行,但在 :global命令的上下文中,它则表示 {pattern} 的匹配行。
可以把原有的命令拆分成两条单独的Ex命令进行讲解,先分析命令的后半部分。以下是一条有效的Ex命令。
➾ :.+1,/}/-1 sort
如果去掉范围中的偏移,该范围可简化为 .,/}/,其含义是“从当前行开始,一直到匹配模式 /}/ 的那一行为止”。偏移值 +1 与 —1 仅仅用于缩小操作范围,让我们把目光集中在 {} 之间的内容上面。对于排序前的原始CSS文件,如果把光标置于第1行或第9行,以上这条Ex命令将会对相应 {} 之内的规则按照字母顺序重新排序。
也就是说,只需将光标置于每个{} 块的起始位置,再运行 :.,/}/ sort 命令,即可将其中的规则按照字母顺序重新排序了。明白了么?现在,试着用 :global命令中的 {pattern} 执行一次查找。
➾ /{/
以上命令会将光标置于某个 {} 块的起始位置,即我们的目标所在。现在,再重新将 :global 与 Ex命令 [cmd]组合在一起。
➾ :g/{/ .+1,/}/—1 sort
其中,模式 { 会匹配每个 {} 块的起始行。而对于每个匹配行,:sort会在匹配行到 {} 块的结尾这个[range] 范围内执行。最终,每一条规则的CSS属性都会按照字母顺序排列整齐。